package com.qzdsoft.erpcloud.interceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.github.pagehelper.util.StringUtil;
import com.qzdsoft.JWTProperties;
import com.qzdsoft.erpcloud.domain.sys.LoginUser;
import com.qzdsoft.erpcloud.service.sys.RedisService;
import com.qzdsoft.utils.JsonUtils;
import com.qzdsoft.utils.JwtHelper;
import com.qzdsoft.utils.SysUtils;

import io.jsonwebtoken.Claims;

@Component
public class UserLoginInterceptor implements HandlerInterceptor
{

    private Logger logger = LoggerFactory.getLogger(UserLoginInterceptor.class);
    
    @Value("${login.validate}")
    private boolean loginValidate;
    
    @Autowired
    private JWTProperties jWTProperties;
    
    @Autowired
    private RedisService redisService;
    
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception
    {
        
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception
    {
        
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
      //如果配置文件配置不需要登录验证 直接返回true （开发时可以配置为false）
        if(loginValidate==false) {
            return true;
        }
        //Object uidObj = SessionUtil.getLoggedId(request);
        Cookie cookies[] = request.getCookies();
        String token = "";
        String uid = "";
        if(cookies==null) {
            return false;
        }
        for(Cookie c:cookies) {
            logger.debug("获取到的token:{},value:{}",c.getName(),c.getValue());
            if("authtoken".equals(c.getName())) {
                token = c.getValue();
            }
            if("uid".equals(c.getName())) {
                uid = c.getValue();
            }
        }
        if(!StringUtil.isEmpty(token)) {
            logger.debug("获取到token不为空：{}",token);
            Claims claims = JwtHelper.parseJWT(token, jWTProperties.getBase64Security());
            logger.debug("获取到token不为空：{}，claims={}",token,claims);
            if(claims!=null) {
                Integer id = claims.get("id", Integer.class);
                if(!id.toString().equals(uid)) {
                    logger.error("参数错误uid:{},和token中uid:{}不一致",uid,id);
                    throw new RuntimeException("参数错误uid和token中uid不一致");
                }
                Object userJson = redisService.get(SysUtils.redisUserSessionId(id));
                logger.debug("获取到的redis登录用户信息：{}",userJson);
                if(userJson!=null) {
                    LoginUser user = JsonUtils.jsonToPojo(userJson.toString(), LoginUser.class);
                    request.setAttribute("user", user);
                    String uuid = claims.get("uuid",String.class);
                    if(!uuid.equals(user.getUuid())) {
                        logger.warn("用户异地登录：token uuid:{},redis uuid:{}",uuid,user.getUuid());
                        if(isAjaxRequest(request)) {
                            response.setHeader("togetherlogin", "true");// 在响应头设置permn状态
                        }else {
                            response.sendRedirect("/login.html?cxdl=2");
                        }
                        return false;
                    }
                    return true;
                }
            }
        }
        logger.warn("登录失效，需要重新登录");
        if(isAjaxRequest(request)) {
            response.setHeader("sessionstatus", "false");// 在响应头设置permn状态
        }else {
            response.sendRedirect("/login.html?cxdl=1");
        }
        return false;
    }
    private boolean isAjaxRequest(HttpServletRequest request) {
        return request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest");// 如果是ajax请求响应头会有，x-requested-with；
    }
}
